home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / plotting / imagetoo / imagetl1.lha / Imagetool / HDF / dfkit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-20  |  11.2 KB  |  403 lines

  1. /*****************************************************************************
  2. *              NCSA HDF version 3.10
  3. *                July 1, 1990
  4. *
  5. * NCSA HDF Version 3.10 source code and documentation are in the public
  6. * domain.  Specifically, we give to the public domain all rights for future
  7. * licensing of the source code, all resale rights, and all publishing rights.
  8. * We ask, but do not require, that the following message be included in all
  9. * derived works:
  10. * Portions developed at the National Center for Supercomputing Applications at
  11. * the University of Illinois at Urbana-Champaign.
  12. * THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESSED OR IMPLIED, FOR THE
  13. * SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT LIMITATION,
  14. * WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE
  15. *****************************************************************************/
  16.  
  17. #ifdef RCSID
  18. static char RcsId[] = "@(#)$Revision: 3.10 $"
  19. #endif
  20. /*
  21. $Header: /pita/work/HDF/dev/RCS/src/dfkit.c,v 3.10 90/07/02 09:37:52 clow beta $
  22. $Log:    dfkit.c,v $
  23.  * Revision 3.10  90/07/02  09:37:52  clow
  24.  * enclosed DFconvert macro and function with an #ifdef on FUNC_CONV
  25.  * so that the selection between these is a compilation option
  26.  * 
  27.  * Revision 3.9  90/06/21  10:40:53  clow
  28.  * Changes UNICOS conversion functions for non-UNICOS env to be similar
  29.  * to the UNICOS fortran functions, and
  30.  * "#if 0" out the DFconvert function, use macro in dfconvert.h
  31.  * 
  32.  * Revision 3.8  90/06/07  17:39:28  clow
  33.  * bug fix in conversion routines
  34.  * 
  35. */
  36. /*
  37.  * Changes:
  38.  *    DFconvert() calls FORTRAN conversion routines if compiled with UNICOS 
  39.  *    DFconvert() takes an array rather than a single number
  40.  *    Register parameters have been declared
  41.  *    Pointers are now used rather than array indexing
  42.  */
  43. /* Modified DFconvert so that it takes an array rather than a single number */
  44. /* Now call FORTRAN conversion routines */
  45. #include <ctype.h>
  46. #include "df.h"
  47.  
  48. union fpx
  49. {
  50.      float f;
  51.      long  l;
  52. };
  53.  
  54. union float_uint_uchar {
  55.     float32 f;
  56.     int32 i;
  57.     unsigned char c[4];
  58. };
  59.  
  60. char *DFIstrncpy(dest, source, len)
  61. register char *source, *dest;
  62. int len;
  63. {
  64.  
  65.     for(; (--len > 0) && (*dest++ = *source++););
  66.     if (!len) *dest = '\0';
  67.     return(dest);
  68. }
  69.  
  70. #ifdef FUNC_CONV
  71. /* function convert, otherwise, this function is done in macro (dfconvert.h) */
  72. int DFconvert(source, dest, ntype, sourcetype, desttype, size)
  73. char *source, *dest;
  74. int ntype;
  75. register int sourcetype, desttype;
  76. int size;
  77. {
  78.     register char t;      /* Temporary, used in byte-swapping */
  79.     register int i;
  80.     int status;
  81.  
  82.     if (ntype==DFNT_FLOAT) {
  83.  
  84.     if (((sourcetype==DFNTF_IEEE) && ( desttype==DFNTF_PC)) ||
  85.         ((sourcetype==DFNTF_PC) && (desttype==DFNTF_IEEE))) {
  86.             for (i=0; i<size*4; i+=4)
  87.               {
  88.             dest[i  ] = source[i+3];
  89.             dest[i+1] = source[i+2];
  90.             dest[i+2] = source[i+1];
  91.             dest[i+3] = source[i  ];
  92.               }
  93.         return(0);
  94.     }
  95.  
  96.     /* if reversed IEEE, reverse before conversion */
  97.     if (sourcetype==DFNTF_PC) {
  98.       sourcetype=DFNTF_IEEE;
  99.           for (i=0; i<size*4; i+=4)
  100.             {
  101.           t           = source[i];
  102.           source[i  ] = source[i+3];
  103.               source[i+3] = t;
  104.           t           = source[i+1];
  105.           source[i+1] = source[i+2];
  106.               source[i+2] = t;
  107.             }
  108.     }
  109.  
  110.         if ((sourcetype==DFNTF_IEEE) && (desttype==DFNTF_CRAY)) {
  111. #ifdef UNICOS
  112.             SCUP32(source, dest, &size, &status);
  113. #else
  114.             if (DFCVieeeF2unicosF(source,(union fpx*) dest, size)<0)
  115.                return(-1);
  116. #endif
  117.         } else if ((sourcetype==DFNTF_CRAY) &&
  118.            ((desttype==DFNTF_IEEE) || (desttype==DFNTF_PC))) {
  119. #ifdef UNICOS
  120.             CSPK32(source, dest, &size, &status);
  121. #else
  122.             if (DFCVunicosF2ieeeF((union fpx*)source, dest, size)<0) 
  123.                return(-1);
  124. #endif
  125.     }
  126.  
  127.         if ((sourcetype==DFNTF_IEEE) && (desttype==DFNTF_VAX)) {
  128.             if (DFCVieeeF2vaxF((union float_uint_uchar *) source,
  129.                    (union float_uint_uchar *) dest, size)<0)
  130.         return(-1);
  131.         } else if ((sourcetype==DFNTF_VAX) &&
  132.            ((desttype==DFNTF_IEEE) || (desttype==DFNTF_PC))) {
  133.             if (DFCVvaxF2ieeeF((union float_uint_uchar*) source,
  134.                    (union float_uint_uchar*) dest, size)<0)
  135.         return(-1);
  136.         }
  137.  
  138.     /* if reversed IEEE, reverse result */
  139.     if (desttype==DFNTF_PC) {
  140.           for (i=0; i<size*4; i+=4)
  141.             {
  142.           t         = dest[i+3];
  143.           dest[i+3] = dest[i];
  144.           dest[i  ] = t;
  145.           t         = dest[i+2];
  146.           dest[i+2] = dest[i+1];
  147.           dest[i+1] = t;
  148.             }
  149.     }
  150.     return(0);
  151.     }
  152.         /* default */
  153.     DFerror = DFE_BADCONV;
  154.     return(-1);
  155. }
  156. #endif /* FUNC_CONV */
  157.  
  158. char *DFIgetspace(qty)
  159. unsigned qty;
  160. {
  161.     char *p;
  162.  
  163.     p = malloc(qty);
  164.     if (p==NULL) {
  165.         DFerror = DFE_NOSPACE;
  166.         return(NULL);
  167.     }
  168.     return(p);
  169. }
  170.  
  171. char *DFIfreespace(ptr)
  172. char *ptr;
  173. {
  174.     if (ptr!=NULL) free(ptr);
  175.     return(NULL);
  176. }
  177.  
  178.  
  179. #ifdef UNICOS
  180.  
  181. #define MINEXP    0x3f81000000000000  /* min valid Cray masked exponent */
  182. #define MAXEXP    0x407e000000000000  /* max valid Cray masked exponent */
  183.  
  184. #define C_FMASK   0x00007fffff000000  /* Cray fraction mask (1st 23 bits)*/
  185. #define C_EMASK   0x7fff000000000000  /* Cray exponent mask */
  186. #define C_SMASK   0x8000000000000000  /* Cray sign mask */
  187. #define C_IMPLICIT 0x0000800000000000 /* Cray implicit bit */
  188.  
  189. #define I_FMASK   0x007fffff          /* IEEE fraction mask */
  190. #define I_EMASK   0x7f800000          /* IEEE exponent mask */
  191. #define I_SMASK   0x80000000          /* IEEE sign mask     */
  192.  
  193. #define IEEE_BIAS 0177
  194. #define CRAY_BIAS 040000
  195.  
  196. #endif /*UNICOS*/
  197.  
  198. /* On UNICOS, this function is defined as a fortran function */
  199. #ifndef UNICOS
  200.     /*  convert from Cray2 floating point format to IEEE format */
  201. /* shut lint up */
  202. /* ARGSUSED */
  203. CSPK32(cray_fp, ieee_fp, size, status)
  204. char *cray_fp;
  205. char *ieee_fp;
  206. int *size;
  207. int *status;
  208. {
  209.     DFerror = DFE_BADCONV;
  210.     *status = -1;
  211. }
  212. #endif /*!UNICOS*/
  213.  
  214. #if 0
  215. /* Old cray conversion routine */
  216.     register int i;
  217.     register long C2I_diff;
  218.     long tmp;
  219.     C2I_diff = (IEEE_BIAS - CRAY_BIAS - 1) << 48;
  220.     for (i=0; i<size; i++, cray_fp++, ieee_fp+=4)
  221.       {
  222.         if (cray_fp->l == 0)
  223.           tmp = 0;
  224.         else {
  225.           tmp = (C_EMASK & cray_fp->l);
  226.           if (tmp < MINEXP || tmp > MAXEXP) {
  227.               DFerror = DFE_BADFP;
  228.               return(-1);
  229.           }
  230.  
  231.           tmp = ((tmp + C2I_diff) << 7)
  232.             | ( (cray_fp->l & C_FMASK) << 8 )
  233.             | ( (cray_fp->l & C_SMASK));
  234.         }
  235.         DFmovmem((char *)&tmp, ieee_fp, 4);
  236.       }
  237.     return(0);
  238. }
  239. #endif /* 0 */
  240.  
  241. /* On UNICOS, this function is defined as a fortran function */
  242. #ifndef UNICOS
  243. /* Conversion from IEEE floating point format to Cray format */
  244. /* shut lint up */
  245. /* ARGSUSED */
  246. SCUP32(ieee_fp, cray_fp, size, status)
  247. char *cray_fp;
  248. char *ieee_fp;
  249. int *size;
  250. int *status;
  251. {
  252.     DFerror = DFE_BADCONV;
  253.     *status = -1;
  254. }
  255. #endif /*!UNICOS*/
  256.  
  257. #if 0
  258. register union fpx *cray_fp;
  259. register char *ieee_fp;
  260. int size;
  261. {
  262.     long tmp;
  263.     register int i;
  264.     register long I2C_diff;
  265.  
  266.     I2C_diff = (CRAY_BIAS - IEEE_BIAS + 1) << 23;
  267.     for (i=0; i<size; i++, ieee_fp+=4, cray_fp++)
  268.       {
  269.         tmp = 0;
  270.         DFmovmem(ieee_fp, ((char *) &tmp) + 4, 4); 
  271.  
  272.         if ( (cray_fp->l = tmp & I_EMASK) == 0) {
  273.           cray_fp->l = 0;
  274.           continue;
  275.         }
  276.  
  277.         cray_fp->l += I2C_diff;
  278.         cray_fp->l = (cray_fp->l<< 25)
  279.            | ( (tmp & I_FMASK) << 24)
  280.            | ( (tmp & I_SMASK) << 32)
  281.        | C_IMPLICIT;
  282.       }
  283.     return (0);
  284.  
  285. }
  286. #endif /* 0 */
  287.  
  288. DFIc2fstr(str, len)
  289. char* str;
  290. int len;
  291. {
  292.     int i;
  293.  
  294.     for(i=0; (str[i]); i++);
  295.     for(; i<len; i++) str[i] = ' ';
  296. }
  297.  
  298. char *DFIf2cstring(fdesc, len)
  299.     _fcd fdesc;
  300.     int len;
  301. {
  302.     char *cstr, *str;
  303.     int i;
  304.  
  305.     str = _fcdtocp(fdesc);
  306.     for(i=len-1;i>=0 && (!isascii(str[i]) || !isgraph(str[i])); i--)
  307.     /*EMPTY*/;
  308.     cstr = DFIgetspace(i+2);
  309.     cstr[i+1] = '\0';
  310.     for (; i>=0; i--) cstr[i] = str[i];
  311.     return cstr;
  312. }
  313.  
  314. int DFCVvaxF2ieeeF(in, out, size)
  315. union float_uint_uchar in[], out[];
  316. int size;
  317. {
  318.     register unsigned char exp;
  319.     int i;
  320.  
  321.     for (i=0; i<size; i++)
  322.       {
  323.         exp = (in[i].c[1] << 1) | (in[i].c[0] >> 7);  /* extract exponent */
  324.         if (!exp && !in[i].c[1]) out[i].i = 0;        /* zero value */
  325.         else if (exp>2) {                               /* normal value */
  326.             out[i].c[0] = in[i].c[1] - 1; /* subtracts 2 from exponent */
  327.                 /* copy mantissa, LSB of exponent */
  328.             out[i].c[1] = in[i].c[0];
  329.             out[i].c[2] = in[i].c[3];
  330.             out[i].c[3] = in[i].c[2];
  331.         }
  332.         else if (exp) {                          /* denormalized number */
  333.             register int shft;
  334.  
  335.             out[i].c[0] = in[i].c[1] & 0x80;   /* keep sign, zero exponent */
  336.             shft = 3 - exp;
  337.             /* shift original mant by 1 or 2 to get denormalized mant */
  338.             /* prefix mantissa with '1'b or '01'b as appropriate */
  339.             out[i].c[1] = ((in[i].c[0] & 0x7f) >> shft) | (0x10 << exp);
  340.             out[i].c[2] = (in[i].c[0] << (8-shft)) | (in[i].c[3] >> shft);
  341.             out[i].c[3] = (in[i].c[3] << (8-shft)) | (in[i].c[2] >> shft);
  342.         }
  343.         else {                                  /* sign=1 -> infinity or NaN */
  344.             out[i].c[0] = 0xff;                /* set exp to 255 */
  345.                 /* copy mantissa */
  346.             out[i].c[1] = in[i].c[0] | 0x80;  /* LSB of exp = 1 */
  347.             out[i].c[2] = in[i].c[3];
  348.             out[i].c[3] = in[i].c[2];
  349.         }
  350.       }
  351.     return(0);
  352. }
  353.  
  354.  
  355. int DFCVieeeF2vaxF(in, out, size)
  356. union float_uint_uchar in[], out[];
  357. int size;
  358. {
  359.     register unsigned char exp;
  360.     int i;
  361.  
  362.     for (i=0; i<size; i++)
  363.       {
  364.          exp = (in[i].c[0] << 1) | (in[i].c[1] >> 7); /* extract exponent */
  365.          if (exp) {                                  /* non-zero exponent */
  366.             /* copy mantissa, last bit of exponent */
  367.            out[i].c[0] = in[i].c[1];
  368.            out[i].c[2] = in[i].c[3];
  369.            out[i].c[3] = in[i].c[2];
  370.            if (exp<254)                        /* normal value */
  371.              out[i].c[1] = in[i].c[0] + 1;   /* actually adds two to exp */
  372.            else {                              /* infinity or NaN */
  373.              if (exp==254)                     /* unrepresentable - OFL */
  374.                out[i].i = 0;                  /* set mant=0 for overflow */
  375.             out[i].c[0] &= 0x7f;              /* set last bit of exp to 0 */
  376.             out[i].c[1] = 0x80;               /* sign=1 exp=0 -> OFL or NaN */
  377.           }
  378.         }
  379.         else if (in[i].c[1] & 0x60) {               /* denormalized value */
  380.           register int shft;
  381.     
  382.           shft = (in[i].c[1] & 0x40) ? 1 : 2;  /* shift needed to normalize */
  383.             /* shift mantissa */
  384.             /* note last bit of exp set to 1 implicitly */
  385.           out[i].c[0] = (in[i].c[1] << shft) & (in[i].c[2] >> (8-shft));
  386.           out[i].c[3] = (in[i].c[2] << shft) & (in[i].c[3] >> (8-shft));
  387.           out[i].c[2] = in[i].c[3] << shft;
  388.           out[i].c[1] = (in[i].c[0] & 0x80);          /* sign */
  389.           if (shft==1) {                          /* set exp to 2 */
  390.             out[i].c[1] |= 0x01;
  391.             out[i].c[0] &= 0x7f;                  /* set LSB of exp to 0 */
  392.           }
  393.         }
  394.         else out[i].i = 0;                            /* zero */
  395.       }
  396.     return(0);
  397. }
  398.